﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Net;
using System.IO;
using System.Text;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using Kalman;
using WxPayAPI;
using Kalman.Logging;
using Microsoft.AspNetCore.Http;

namespace QuDao
{
    /// <summary>
    /// 微信企业转账功能：包括发红包、转微信钱包、转银行账号
    /// </summary>
    public class WxTransfer
    {
        //private readonly IHttpContextAccessor _httpContextAccessor;

        //public WxTransfer(IHttpContextAccessor httpContextAccessor)
        //{
        //    _httpContextAccessor = httpContextAccessor;
        //}

        #region 发红包

        /// <summary>
        /// 发送普通红包（服务商模式），API文档参考：https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon_sl.php?chapter=13_4&index=3
        /// </summary>
        /// <param name="openID">红包接收用户的OpenID</param>
        /// <param name="amount">红包金额，1-200，超过200需要设置</param>
        /// <param name="billno">红包订单号，默认空表示自动生成</param>
        /// <param name="actName">活动名称，长度不超过32</param>
        /// <param name="wishing">红包祝福语，长度不超过128</param>
        /// <param name="remark">备注信息，长度不超过256</param>
        /// <param name="sceneID">发放红包使用场景，红包金额大于200时必传（PRODUCT_1:商品促销 PRODUCT_2:抽奖 PRODUCT_3:虚拟物品兑奖  PRODUCT_4:企业内部福利 PRODUCT_5:渠道分润 PRODUCT_6:保险回馈 PRODUCT_7:彩票派奖 PRODUCT_8:税务刮奖）</param>
        public string SendRedPack(string openID, decimal amount, string billno = "", string actName = "普通红包", string wishing = "恭喜发财，大吉大利！", string remark = "红包已放入零钱账户，请注意查收", string sceneID = "")
        {
            string url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";

            WxPayData data = new WxPayData();
            //data.SetValue("body", body);
            data.SetValue("nonce_str", WxPayApi.GenerateNonceStr());//随机字符串
            data.SetValue("mch_billno", billno == "" ? DateTime.Now.ToString("yyyyMMddHHmmssfffff") : billno);//商户订单号，最大28位
            //data.SetValue("send_name", partner.PartnerName);//商户名称，红包发送者名称
            //data.SetValue("sub_appid", partner.WxAppID);//小程序的APPID sub_appid 是 String(32) wx8888888888888888 当前调起支付的小程序APPID 

            data.SetValue("total_amount", decimal.Round(amount * 100, 0).ToString());//红包金额,以分为单位(amount * 100).ToString()
            data.SetValue("re_openid", openID);//接受红包的用户，用户在wxappid下的openid
            data.SetValue("total_num", "1");//红包发放总人数 total_num=1
            data.SetValue("wishing", wishing);//红包祝福语 128
            data.SetValue("client_ip", WxPayConfig.IP);//终端ip	  	    
            data.SetValue("act_name", actName);//
            data.SetValue("remark", remark);//

            //可选参数
            if (amount > 200)//发放红包使用场景，红包金额大于200时必传
            {
                //PRODUCT_1:商品促销 PRODUCT_2:抽奖 PRODUCT_3:虚拟物品兑奖  PRODUCT_4:企业内部福利 PRODUCT_5:渠道分润 PRODUCT_6:保险回馈 PRODUCT_7:彩票派奖 PRODUCT_8:税务刮奖
                data.SetValue("scene_id", sceneID);
            }

            /*  活动信息：posttime%3d123123412%26clientversion%3d234134%26mobile%3d122344545%26deviceid%3dIOS
             *  posttime:用户操作的时间戳 
                mobile:业务系统账号的手机号，国家代码-手机号。不需要+号 
                deviceid :mac 地址或者设备唯一标识  
                clientversion :用户操作的客户端版本 
                把值为非空的信息用key=value进行拼接，再进行urlencode 
                urlencode(posttime=xx& mobile =xx&deviceid=xx)
             */
            //data.SetValue("risk_info", "");//

            #region 普通商户模式
            //data.SetValue("wxappid", partner.WxAppID);//微信分配的公众账号ID  
            //data.SetValue("mch_id", partner.WxPayMCHID);//商户号 mch_id 是 String(32) 1230000109 微信支付分配的商户号 
            ////签名
            //data.SetValue("sign", data.MakeSign("fm54U5udZMdwrzALzw0owSeE71ACNcwk")); //

            //string xml = data.ToXml();
            //string response = Post(xml, url, true, 60, false);   //统一下单
            //return response;
            #endregion

            #region 服务商模式
            data.SetValue("wxappid", WxPayConfig.APPID);//服务商ID appid 是 String(32) wxd678efh567hg6787 微信分配的公众账号ID  
            data.SetValue("mch_id", WxPayConfig.MCHID);//商户号 mch_id 是 String(32) 1230000109 微信支付分配的商户号 
            //data.SetValue("sub_mch_id", partner.WxPayMCHID);//微信支付分配的子商户号，服务商模式下必填
            //data.SetValue("msgappid", partner.WxAppID);//服务商模式下触达用户时的appid(可填服务商自己的appid或子商户的appid)，服务商模式下必填，服务商模式下填入的子商户appid必须在微信支付商户平台中先录入，否则会校验不过。
            //data.SetValue("consume_mch_id", partner.WxPayMCHID);//扣钱方mchid，常规模式下无效，服务商模式下选填，服务商模式下不填默认扣子商户的钱 
            //签名
            data.SetValue("sign", data.MakeSign());

            string xml = data.ToXml();
            string response = Post(xml, url, true, 60, true);   //统一下单
            //WxPayData result = new WxPayData();
            //result.FromXml(response);
            return response;
            #endregion
        }

        /// <summary>
        /// 发送裂变红包（服务商模式），API文档参考：https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon_sl.php?chapter=13_5&index=4
        /// </summary>
        /// <param name="openID">接收红包的种子用户（首个用户）用户在wxappid下的openid</param>
        /// <param name="billno">红包订单号，默认空表示自动生成</param>
        /// <param name="amount">红包金额，1-200，超过200需要设置</param>
        /// <param name="num">红包发放总人数，即总共有多少人可以领到该组红包（包括分享者）</param>
        /// <param name="actName">活动名称，长度不超过32</param>
        /// <param name="wishing">红包祝福语，长度不超过128</param>
        /// <param name="remark">备注信息，长度不超过256</param>
        /// <param name="sceneID">发放红包使用场景，红包金额大于200时必传（PRODUCT_1:商品促销 PRODUCT_2:抽奖 PRODUCT_3:虚拟物品兑奖  PRODUCT_4:企业内部福利 PRODUCT_5:渠道分润 PRODUCT_6:保险回馈 PRODUCT_7:彩票派奖 PRODUCT_8:税务刮奖）</param>
        public string SendGroupRedPack(string openID, decimal amount, int num, string billno = "", string actName = "抢红包", string wishing = "恭喜发财，大吉大利！", string remark = "红包已放入零钱账户，请注意查收", string sceneID = "")
        {
            string url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack";

            WxPayData data = new WxPayData();
            //data.SetValue("body", body);
            data.SetValue("nonce_str", WxPayApi.GenerateNonceStr());//随机字符串
            data.SetValue("mch_billno", billno == "" ? DateTime.Now.ToString("yyyyMMddHHmmssfffff") : billno);//商户订单号，最大28位
            //data.SetValue("send_name", partner.PartnerName);//商户名称，红包发送者名称

            data.SetValue("total_amount", decimal.Round(amount * 100, 0).ToString());//红包金额,以分为单位(amount * 100).ToString()
            data.SetValue("total_num", num.ToString());//红包发放总人数，即总共有多少人可以领到该组红包（包括分享者） ,3-20
            data.SetValue("amt_type", "ALL_RAND");//红包金额设置方式 ALL_RAND—全部随机,商户指定总金额和红包发放总人数，由微信支付随机计算出各红包金额 
            data.SetValue("re_openid", openID);//接收红包的种子用户（首个用户）用户在wxappid下的openid

            data.SetValue("wishing", wishing);//红包祝福语 128
            data.SetValue("client_ip", WxPayConfig.IP);//终端ip	  	    
            data.SetValue("act_name", actName);//
            data.SetValue("remark", remark);//

            //可选参数
            if (amount > 200)//发放红包使用场景，红包金额大于200时必传
            {
                //PRODUCT_1:商品促销 PRODUCT_2:抽奖 PRODUCT_3:虚拟物品兑奖  PRODUCT_4:企业内部福利 PRODUCT_5:渠道分润 PRODUCT_6:保险回馈 PRODUCT_7:彩票派奖 PRODUCT_8:税务刮奖
                data.SetValue("scene_id", sceneID);
            }

            /*  活动信息：posttime%3d123123412%26clientversion%3d234134%26mobile%3d122344545%26deviceid%3dIOS
             *  posttime:用户操作的时间戳 
                mobile:业务系统账号的手机号，国家代码-手机号。不需要+号 
                deviceid :mac 地址或者设备唯一标识  
                clientversion :用户操作的客户端版本 
                把值为非空的信息用key=value进行拼接，再进行urlencode 
                urlencode(posttime=xx& mobile =xx&deviceid=xx)
             */
            //data.SetValue("risk_info", "");//

            data.SetValue("wxappid", WxPayConfig.APPID);//服务商ID appid 是 String(32) wxd678efh567hg6787 微信分配的公众账号ID  
            data.SetValue("mch_id", WxPayConfig.MCHID);//商户号 mch_id 是 String(32) 1230000109 微信支付分配的商户号 
            //data.SetValue("sub_mch_id", partner.WxPayMCHID);//微信支付分配的子商户号，服务商模式下必填
            //data.SetValue("msgappid", partner.WxAppID);//服务商模式下触达用户时的appid(可填服务商自己的appid或子商户的appid)，服务商模式下必填，服务商模式下填入的子商户appid必须在微信支付商户平台中先录入，否则会校验不过。
            //data.SetValue("consume_mch_id", partner.WxPayMCHID);//扣钱方mchid，常规模式下无效，服务商模式下选填，服务商模式下不填默认扣子商户的钱 
            //签名
            data.SetValue("sign", data.MakeSign());

            string xml = data.ToXml();
            string response = Post(xml, url, true, 60, true);   //统一下单
            //WxPayData result = new WxPayData();
            //result.FromXml(response);
            return response;
        }

        /// <summary>
        /// 查询红包记录，API文档参考：https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_6&index=5
        /// </summary>
        /// <param name="billno">商户订单号</param>
        public string QueryRedPack(string billno)
        {
            string url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo";

            WxPayData data = new WxPayData();
            //data.SetValue("body", body);
            data.SetValue("nonce_str", WxPayApi.GenerateNonceStr());//随机字符串
            data.SetValue("mch_billno", billno);//商户订单号，最大28位
            data.SetValue("bill_type", "MCHT");//MCHT:通过商户订单号获取红包信息。 

            data.SetValue("appid", WxPayConfig.APPID);//服务商ID appid 是 String(32) wxd678efh567hg6787 微信分配的公众账号ID  
            data.SetValue("mch_id", WxPayConfig.MCHID);//商户号 mch_id 是 String(32) 1230000109 微信支付分配的商户号 
            //签名
            data.SetValue("sign", data.MakeSign());

            string xml = data.ToXml();
            string response = Post(xml, url, true, 60, true);   //统一下单
            //WxPayData result = new WxPayData();
            //result.FromXml(response);
            return response;
        }

        #endregion

        #region 企业付款

        ///// <summary>
        ///// 企业付款到零钱，API文档参考：https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2#
        ///// </summary>
        ///// <param name="openID">用户openid</param>
        ///// <param name="billno">商户订单号</param>
        ///// <param name="amount">付款金额（元）</param>
        ///// <param name="checkName">是否强制校验真实姓名，默认不校验</param>
        ///// <param name="trueName">用户真实姓名</param>
        ///// <param name="desc">企业付款描述信息</param>
        //public WxPayData PayToWxBalance(Merchant mch, string openID, decimal amount, string desc = "", string billno = "", bool checkName = false, string trueName = "")
        //{
        //    var url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";

        //    var data = new WxPayData();
        //    //data.SetValue("body", body);
        //    data.SetValue("nonce_str", WxPayApi.GenerateNonceStr());//随机字符串
        //    data.SetValue("partner_trade_no", billno);//商户订单号 partner_trade_no，商户订单号，需保持唯一性(只能是字母或者数字，不能包含有符号) 
        //    data.SetValue("mch_appid", mch.AppID);//商户账号appid mch_appid 是 wx8888888888888888 String 微信分配的账号ID（企业号corpid即为此appId） 
        //    data.SetValue("mchid", mch.MchID);//商户号 mchid 是 1900000109 String(32) 微信支付分配的商户号 
        //    //data.SetValue("device_info", "");//设备号 device_info 否 013467007045764 String(32) 微信支付分配的终端设备号 
        //    data.SetValue("openid", openID);//用户openid openid 是 oxTWIuGaIt6gTKsQRLau2M0yL16E String 商户appid下，某用户的openid 

        //    if (checkName)
        //    {
        //        data.SetValue("check_name", "FORCE_CHECK");//校验用户姓名选项 check_name 是 FORCE_CHECK String NO_CHECK：不校验真实姓名 FORCE_CHECK：强校验真实姓名 
        //        data.SetValue("re_user_name", trueName);//收款用户姓名 re_user_name 可选 王小王 String 收款用户真实姓名。 如果check_name设置为FORCE_CHECK，则必填用户真实姓名 
        //    }
        //    else
        //    {
        //        data.SetValue("check_name", "NO_CHECK");//校验用户姓名选项 check_name 是 FORCE_CHECK String NO_CHECK：不校验真实姓名 FORCE_CHECK：强校验真实姓名 
        //    }

        //    data.SetValue("amount", decimal.Round(amount * 100, 0).ToString());//金额 amount 是 10099 int 企业付款金额，单位为分 
        //    data.SetValue("desc", desc);//企业付款描述信息 desc 是 理赔 String 企业付款操作说明信息。必填。 
        //    data.SetValue("spbill_create_ip", WxPayConfig.IP);//Ip地址 spbill_create_ip 是 192.168.0.1 String(32) 调用接口的机器Ip地址 

        //    //签名
        //    data.SetValue("sign", data.MakeSign(WxPayConfig.KEY));

        //    var xml = data.ToXml();
        //    var response = Post(xml, url, true, 60, false);
        //    var result = new WxPayData();
        //    result.FromXml(response);
        //    return result;
        //}

        /// <summary>
        /// 查询企业付款，查询企业付款API只支持查询30天内的订单，30天之前的订单请登录商户平台查询。API文档参考：https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3
        /// </summary>
        /// <param name="billno">商户订单号，默认空表示自动生成</param>
        /// <param name="isBank">是否银行付款</param>
        public WxPayData QueryTransfer(string billno, bool isBank = false)
        {
            string url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo";

            if(isBank)
            {
                url = "	https://api.mch.weixin.qq.com/mmpaysptrans/query_bank";
            }

            WxPayData data = new WxPayData();
            data.SetValue("nonce_str", WxPayApi.GenerateNonceStr());//随机字符串
            data.SetValue("partner_trade_no", billno);//商户订单号  partner_trade_no 是  10000098201411111234567890  String(28)  商户调用企业付款API时使用的商户订单号  

            data.SetValue("mch_appid", WxPayConfig.APPID);//商户账号appid mch_appid 是 wx8888888888888888 String 微信分配的账号ID（企业号corpid即为此appId） 
            data.SetValue("mch_id", WxPayConfig.MCHID);//微信支付分配的商户号

            //签名
            data.SetValue("sign", data.MakeSign());

            string xml = data.ToXml();
            string response = Post(xml, url, true, 60);   //统一下单
            WxPayData result = new WxPayData();
            result.FromXml(response);
            return result;
        }

        /// <summary>
        /// 企业付款到银行卡，API文档参考：https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_2
        /// </summary>
        /// <param name="orderNo">商家订单号</param>
        /// <param name="amount">付款金额，单位：元</param>
        /// <param name="bankName">银行名称，参考：<see cref="https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_4"/></param>
        /// <param name="accountName">银行开户人姓名</param>
        /// <param name="accountNo">银行账号</param>
        /// <param name="desc">企业付款描述信息</param>
        public WxPayData PayToBank(string orderNo, decimal amount, string bankName, string accountName, string accountNo, string desc)
        {
            string url = "https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank";
            string enc_true_name = accountName;//收款方用户名
            string bank_code = bankName;//开户行
            string enc_bank_no = accountNo;//银行卡卡号
            string partner_trade_no = orderNo;//订单编号

            switch (bank_code) //https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_4
            {
                case "工商银行": bank_code = "1002"; break;
                case "农业银行": bank_code = "1005"; break;
                case "中国银行": bank_code = "1026"; break;
                case "建设银行": bank_code = "1003"; break;
                case "招商银行": bank_code = "1001"; break;
                case "邮储银行": bank_code = "1066"; break;
                case "交通银行": bank_code = "1020"; break;
                case "浦发银行": bank_code = "1004"; break;
                case "民生银行": bank_code = "1006"; break;
                case "兴业银行": bank_code = "1009"; break;
                case "平安银行": bank_code = "1010"; break;
                case "中信银行": bank_code = "1021"; break;
                case "华夏银行": bank_code = "1025"; break;
                case "广发银行": bank_code = "1027"; break;
                case "北京银行": bank_code = "1032"; break;
                case "宁波银行": bank_code = "1056"; break;
                default: break;
            }

            int timeOut = 10000;
            //RSATest.RSATest obj = new RSATest.RSATest();
            enc_bank_no = RSAUtils.EncryptCSharp(enc_bank_no, "UTF-8");
            enc_true_name = RSAUtils.EncryptCSharp(enc_true_name, "UTF-8");

            WxPayData data = new WxPayData();
            data.SetValue("mch_id", WxPayConfig.MCHID);//微信支付分配的商户号
            data.SetValue("partner_trade_no", partner_trade_no);//订单号
            data.SetValue("nonce_str", Guid.NewGuid().ToString().Replace("-", ""));// );//随机字符串
            data.SetValue("enc_bank_no", enc_bank_no);//银行卡卡号
            data.SetValue("enc_true_name", enc_true_name);//收款方用户名
            data.SetValue("bank_code", bank_code);//开户行编码
            data.SetValue("amount", decimal.Round(amount * 100, 0).ToString());//付款金额 amount 是 100000 int 付款金额：RMB分（支付总额，不含手续费） 注：大于0的整数 
            data.SetValue("desc", desc);//付款说明
            data.SetValue("sign", data.MakeSign());//签名
            string xml = data.ToXml();//转换xml格式

            //var start = DateTime.Now;//请求开始时间

            string response = HttpService.Post(xml, url, true, timeOut);//调用HTTP通信接口以提交数据到API

            //var end = DateTime.Now;
            //int timeCost = (int)((end - start).TotalMilliseconds);//获得接口耗时

            //将xml格式的结果转换为对象以返回
            var result = new WxPayData();
            result.FromXml(response);
            return result;
        }

        #endregion

        #region private methods

        /// <summary>
        /// 获取RSA公钥，接口默认输出PKCS#1格式的公钥，商户需根据自己开发的语言选择公钥格式。API文档参考：https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_7&index=4
        /// </summary>
        public string GetPublicKey()
        {
            string url = "https://fraud.mch.weixin.qq.com/risk/getpublickey";

            WxPayData data = new WxPayData();
            data.SetValue("nonce_str", WxPayApi.GenerateNonceStr());//随机字符串

            data.SetValue("sign_type", "MD5");//签名类型，支持HMAC-SHA256和MD5。
            data.SetValue("mch_id", WxPayConfig.MCHID);//微信支付分配的商户号

            //签名
            data.SetValue("sign", data.MakeSign());

            string xml = data.ToXml();
            string response = Post(xml, url, true, 60, false);   //统一下单
            WxPayData result = new WxPayData();
            result.FromXml(response);
            
            if(result.GetValue("return_code").ToString() == "SUCCESS")
            {
                if(result.GetValue("result_code").ToString() == "SUCCESS")
                {
                    return result.GetValue("pub_key").ToString();
                }
                else
                {
                    return string.Empty;
                }
            }
            else
            {
                return string.Empty;
            }
        }

        private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            //直接确认，否则打不开    
            return true;
        }

        private string Post(string xml, string url, bool isUseCert, int timeout, bool isService = false)
        {
            System.GC.Collect();//垃圾回收，回收没有正常关闭的http连接

             //=======【证书路径设置】===================================== 
        /* 证书路径,注意应该填写绝对路径（仅退款、撤销订单时需要）
        */
            string result = "";//返回结果
            //string certPath = string.Format("cert/{0}/apiclient_cert.p12", partner.PartnerID);
            //string certPwd = partner.WxPayMCHID;

            //if(isService)
            //{
            //    //certPath = "cert/apiclient_cert.p12";
            //    //certPwd = WxPayConfig.MCHID;
            //}

            HttpWebRequest request = null;
            HttpWebResponse response = null;
            Stream reqStream = null;

            try
            {
                //设置最大连接数
                ServicePointManager.DefaultConnectionLimit = 200;
                //设置https验证方式
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    ServicePointManager.ServerCertificateValidationCallback =
                            new RemoteCertificateValidationCallback(CheckValidationResult);
                }

                /***************************************************************
                * 下面设置HttpWebRequest的相关属性
                * ************************************************************/
                request = (HttpWebRequest)WebRequest.Create(url);

                request.Method = "POST";
                request.Timeout = timeout * 1000;

                //设置代理服务器
                //WebProxy proxy = new WebProxy();                          //定义一个网关对象
                //proxy.Address = new Uri(WxPayConfig.PROXY_URL);              //网关服务器端口:端口
                //request.Proxy = proxy;

                //设置POST的数据类型和长度
                request.ContentType = "text/xml";
                byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
                request.ContentLength = data.Length;

                //是否使用证书
                if (isUseCert)
                {
                    //string path = HttpContext.Current.Request.PhysicalApplicationPath;
                    //X509Certificate2 cert = new X509Certificate2(path + certPath, certPwd);
                    //request.ClientCertificates.Add(cert);
                    
                    string path = AppContext.BaseDirectory;
                    //ILogger log = LogManager.GetCurrentClassLogger();
                    //log.Info(path + @"cert\apiclient_cert.p12");
                    X509Certificate2 cert = new X509Certificate2(path + @"cert\apiclient_cert.p12", WxPayConfig.SSLCERT_PASSWORD, X509KeyStorageFlags.MachineKeySet);
                    request.ClientCertificates.Add(cert);
                    //Log.Debug("WxPayApi", "PostXml used cert");
                }

                //往服务器写入数据
                reqStream = request.GetRequestStream();
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();

                //获取服务端返回
                response = (HttpWebResponse)request.GetResponse();

                //获取服务端返回数据
                StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                result = sr.ReadToEnd().Trim();
                sr.Close();
            }
            catch (System.Threading.ThreadAbortException)
            {
                //Log.Error("HttpService", "Thread - caught ThreadAbortException - resetting.");
                //Log.Error("Exception message: {0}", e.Message);
                System.Threading.Thread.ResetAbort();
            }
            catch (WebException e)
            {
                //Log.Error("HttpService", e.ToString());
                if (e.Status == WebExceptionStatus.ProtocolError)
                {
                    //Log.Error("HttpService", "StatusCode : " + ((HttpWebResponse)e.Response).StatusCode);
                    //Log.Error("HttpService", "StatusDescription : " + ((HttpWebResponse)e.Response).StatusDescription);
                }
                throw new Exception(e.ToString());
            }
            catch (Exception e)
            {
                //Log.Error("HttpService", e.ToString());
                throw new Exception(e.ToString());
            }
            finally
            {
                //关闭连接和流
                response?.Close();
                request?.Abort();
            }
            return result;
        }
        #endregion
    }
}
